package com.pjj.projectservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.example.feignclient.Entity.User;
import com.example.feignclient.client.UserClient;
import com.pjj.base.base.utils.CodeUtil;
import com.pjj.base.base.utils.MathUtil;
import com.pjj.base.base.utils.ResponseUtil;
import com.pjj.projectservice.entity.Project;
import com.pjj.projectservice.entity.Team;
import com.pjj.projectservice.mapper.ProjectMapper;
import com.pjj.projectservice.mapper.TeamMapper;
import com.pjj.projectservice.service.ProjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author 76004
 * @apiNote
 * @date 2023/2/12 23:26
 */
@Service
public class ProjectServiceImpl implements ProjectService {
    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private TeamMapper teamMapper;

    @Autowired
    private UserClient userClient;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    public Object selectById(Long id){
        Map<String,Object> map = new HashMap<>();
        map.put("code",100);
        map.put("msg","查询成功");
        map.put("data",projectMapper.selectById(id));
        return map;
    }

    public Object selectPage(int pageNum,int pageSize){
        Map<String,Object> map = new HashMap<>();
        map.put("code",100);
        map.put("msg","查询成功");
        IPage<Project> page = projectMapper.selectPage(new Page<>(pageNum,pageSize),null);
        map.put("data",page.getRecords());
        return map;
    }

    public Object deleteById(Long id){
        Map<String,Object> map = new HashMap<>();
        map.put("code",100);
        map.put("msg","删除成功");
        projectMapper.deleteById(id);
        //删除项目组成员
        Map<String,Object> columnTeam = new HashMap<>();
        columnTeam.put("project_id",id);
        teamMapper.deleteByMap(columnTeam);
        return map;
    }


    public Object updateProject(Project project){
        Map<String,Object> map = new HashMap<>();
        map.put("code",100);
        map.put("msg","更新成功");
        projectMapper.updateById(project);
        return map;
    }

    public Object selectProjectMemberId(Long id){
        Map<String,Object> map = new HashMap<>();
        map.put("code",100);
        map.put("msg","查询成功");
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("project_id",id);
        map.put("data",teamMapper.selectList(queryWrapper));
        return map;
    }

    public Object addProjectMember(Team team){
        Map<String,Object> map = new HashMap<>();
        map.put("code",100);
        map.put("msg","添加成功");
        teamMapper.insert(team);
        return map;
    }

    public Object selectProjectByUserId(String id){
        Map<String,Object> map = new HashMap<>();
        map.put("code",100);
        map.put("msg","查询成功");
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id",id);
        map.put("data",teamMapper.selectList(queryWrapper));
        return map;
    }

    public Object selectProjectCount(){
        HashMap<String,Object>map = new HashMap<>();
        map.put("code",100);
        map.put("msg","查询成功");
        map.put("data",projectMapper.selectCount(Wrappers.emptyWrapper()));
        return map;
    }

    public Map<String,Object> makeProjectByHighAuthority(Project project) {
        if(Integer.parseInt(userClient.selectCountById(project.getLeaderId()).get("data").toString()) == 1){
            return ResponseUtil.success();
        }
        else{
            return ResponseUtil.fail("用户不存在");
        }
    }

    public Map<String,Object> makeProjectByLeader(Project project) {
        return ResponseUtil.success();
    }

    public Map<String,Object> makeProjectAccessCode(long projectId, long timeout) {
        String code = CodeUtil.generateOnlyCode();
        redisTemplate.opsForValue().set(code,String.valueOf(projectId),timeout, TimeUnit.HOURS);
        return ResponseUtil.success(code);
    }

    public Map<String,Object> makeNoProjectAccessCode(long projectId) {
        redisTemplate.delete(String.valueOf(projectId));
        return ResponseUtil.success();
    }

    @Override
    public Map<String, Object> joinProjectByCode(String userId, String code) {
        Long projectId = new Long(Objects.requireNonNull(redisTemplate.opsForValue().get(code)));
        Team team = new Team();
        team.setProjectId(projectId);
        team.setUserId(userId);
        team.setTimestamp(new Timestamp(new Date().getTime()));
        teamMapper.insert(team);
        return ResponseUtil.success();
    }

    @Override
    public Map<String, Object> removeMemberById(String removeUserId, Long projectId, String requestUserId) {
        teamMapper.delete(new QueryWrapper<Team>().eq("user_id",removeUserId));
        return ResponseUtil.success();
    }

    @Override
    public Map<String, Object> exitProjectById(String userId, Long projectId) {
        Map<String,Object> map = userClient.findById(userId);
        User user = (User) map.get("data");
        teamMapper.delete(new QueryWrapper<Team>().eq("user_id",userId));
        return ResponseUtil.success();
    }

    @Override
    public Boolean authorityVerify(Integer userAuthority, Integer minAuthority) {
        Integer rank = 0;
        if(userAuthority % 3 == 0){
            rank = MathUtil.calculatePow(3,userAuthority);
        }
        else if(userAuthority % 2 == 0){
            rank = MathUtil.calculatePow(2,userAuthority);
        }
        else if(userAuthority % 5 == 0){
            rank = MathUtil.calculatePow(5,userAuthority);
        }
        else{
            return Boolean.FALSE;
        }
        if(rank >= minAuthority){
            return Boolean.TRUE;
        }
        else{
            return Boolean.FALSE;
        }
    }



}
